import subprocess
import os
from urllib.parse import urlparse, urlunparse
from typing import Optional, List, Tuple

class SecureGitManager:
    """安全的Git仓库管理类"""
    
    def __init__(self, repo_path: str = "."):
        self.repo_path = repo_path
    
    def run_command(self, command: list, cwd: Optional[str] = None) -> tuple:
        """执行Git命令"""
        try:
            result = subprocess.run(
                command,
                check=True,
                capture_output=True,
                text=True,
                cwd=cwd or self.repo_path
            )
            return True, result.stdout
        except subprocess.CalledProcessError as e:
            return False, f"命令执行失败: {' '.join(command)}\n错误输出: {e.stderr}\n返回码: {e.returncode}"
        except FileNotFoundError:
            return False, "Git命令未找到，请确保已安装Git"
        except Exception as e:
            return False, f"执行命令时发生未知错误: {' '.join(command)}\n错误信息: {str(e)}"
    
    def get_remote_branches(self, repo_url: str, token: str = '32821a75cfbe7fdc896cb08818944934d6a5e296') -> Tuple[bool, List[str] or str]:
        """
        获取远程仓库的分支列表
        
        Args:
            repo_url: 仓库URL
            token: 访问令牌（默认为预设令牌）
            
        Returns:
            tuple: (success, branches_list or error_message)
        """
        # 如果没有提供仓库URL，使用默认URL
        if not repo_url:
            repo_url = 'http://192.168.1.153:3000/tongyu.frontend/Asst-Manager.git'
            
        # 构建带令牌的URL
        parsed_url = urlparse(repo_url)
        auth_repo_url = urlunparse((
            parsed_url.scheme,
            f"oauth2:{token}@{parsed_url.netloc}",
            parsed_url.path,
            parsed_url.params,
            parsed_url.query,
            parsed_url.fragment
        ))
        
        # 执行 ls-remote 命令获取远程引用
        success, output = self.run_command(['git', 'ls-remote', '--heads', auth_repo_url])
        
        if not success:
            return False, output
        
        # 解析分支名称
        branches = []
        for line in output.strip().split('\n'):
            if line and 'refs/heads/' in line:
                branch_name = line.split('refs/heads/')[-1]
                branches.append(branch_name)
        
        return True, branches
    
    def clone_with_token(self, repo_url: str, local_path: str, token: str = '32821a75cfbe7fdc896cb08818944934d6a5e296', branch: str = 'main') -> bool:
        """使用访问令牌克隆仓库"""
        # 如果没有提供仓库URL，使用默认URL
        if not repo_url:
            repo_url = 'http://192.168.1.153:3000/tongyu.frontend/Asst-Manager.git'
            
        # 构建带令牌的URL (使用token作为用户名，空密码)
        parsed_url = urlparse(repo_url)
        # 对于某些Git服务器，令牌放在用户名位置
        auth_repo_url = urlunparse((
            parsed_url.scheme,
            f"oauth2:{token}@{parsed_url.netloc}",
            parsed_url.path,
            parsed_url.params,
            parsed_url.query,
            parsed_url.fragment
        ))
        
        success, output = self.run_command(['git', 'clone', '-b', branch, auth_repo_url, local_path], cwd=".")
        
        if not success:
            print(f"克隆仓库失败: {output}")
        
        return success
    
    def pull_with_token(self, token: str = '32821a75cfbe7fdc896cb08818944934d6a5e296') -> bool:
        """使用访问令牌拉取更新"""
        # 设置临时凭证助手
        success, _ = self.run_command(['git', 'config', 'credential.helper', 'cache --timeout=300'])
        if not success:
            return False
        
        # 获取当前远程URL
        success, current_url = self.run_command(['git', 'remote', 'get-url', 'origin'])
        if not success:
            return False
        
        # 解析URL并添加认证信息
        parsed_url = urlparse(current_url.strip())
        auth_repo_url = urlunparse((
            parsed_url.scheme,
            f"oauth2:{token}@{parsed_url.netloc}",
            parsed_url.path,
            parsed_url.params,
            parsed_url.query,
            parsed_url.fragment
        ))
        
        # 临时设置认证URL
        self.run_command(['git', 'remote', 'set-url', 'origin', auth_repo_url])
        
        # 拉取更新
        success, output = self.run_command(['git', 'pull'])
        
        # 恢复原始URL
        self.run_command(['git', 'remote', 'set-url', 'origin', current_url.strip()])
        
        return success